package com.txw.javaCore.server.service;

import com.google.gson.Gson;
import com.txw.javaCore.api.enums.Constant;
import com.txw.javaCore.model.request.DelayJobRequest;
import com.txw.javaCore.server.util.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @PROJECT_NAME: JavaCoreB2
 * @DESCRIPTION:
 * @Author: 涂玄武
 * @DATE: 2021/1/5 14:18
 */
@Service
public class MqDelayService {

    private static final Logger log = LoggerFactory.getLogger(MqDelayService.class);

    @Autowired
    private Environment env;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 死信队列处理动态配置的任务 - 只针对延时发送的逻辑
     *
     * @param request
     * @throws Exception
     */
    public void manageDeadJob(DelayJobRequest request) throws Exception {
        //TODO:实际业务中先插入信息到数据库DB中

        //TODO:再根据用户提交的request里面jobTime（设定时间）计算出距离当前时间还有多久发送邮件->TTL,最后交给rabbitMq的死信队列处理
        Date jobTime = Constant.dateFormatThreadLocal.get().parse(request.getJobTime());
        Date currTime = Constant.dateFormatThreadLocal.get().parse(DateUtils.dateTimeNow(Constant.DateTimeFormat));
        Long ttl = jobTime.getTime() - currTime.getTime();
        if (ttl > 0) {
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            rabbitTemplate.setExchange(env.getProperty("mq.order.basic.exchange"));
            rabbitTemplate.setRoutingKey(env.getProperty("mq.order.basic.routing.key"));

            //若传参仅仅是String类型，需将字符串转化为一串二进制的数据流,监听接收的消息采用字节数值类型接收
//            String message = "";
//            Message msg = MessageBuilder.withBody(message.getBytes("UTF-8")).build();
//            rabbitTemplate.convertAndSend(msg);

            String data = new Gson().toJson(request);
            rabbitTemplate.convertAndSend(data, message -> {
                MessageProperties mp = message.getMessageProperties();
                mp.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                //TTL以毫秒作为单位
                mp.setExpiration(ttl.toString());

                log.info("--死信队列处理动态配置的任务 - 只针对延时发送的逻辑-发送消息：msg={},ttl={}", data, ttl);
                return message;
            });
        }

    }

    /**
     * 延迟队列处理动态配置的任务
     *
     * @param request
     * @throws Exception
     */
    public void manageDelayJob(DelayJobRequest request) throws Exception {
        //TODO:实际业务中先插入信息到数据库DB中

        //TODO:再根据用户提交的request里面jobTime（设定时间）计算出距离当前时间还有多久发送邮件->TTL,最后交给rabbitMq的死信队列处理
        Date jobTime = Constant.dateFormatThreadLocal.get().parse(request.getJobTime());
        Date currTime = Constant.dateFormatThreadLocal.get().parse(DateUtils.dateTimeNow(Constant.DateTimeFormat));
        Long ttl = jobTime.getTime() - currTime.getTime();
        if (ttl > 0) {
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            rabbitTemplate.setExchange(env.getProperty("mq.delay.exchange"));
            rabbitTemplate.setRoutingKey(env.getProperty("mq.delay.routing.key"));

            String data = new Gson().toJson(request);
            rabbitTemplate.convertAndSend(data, message -> {
                MessageProperties mp = message.getMessageProperties();
                mp.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                mp.setHeader("x-delay",ttl);
                //若消息的类型是对象，如Person类型
//                mp.setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME,Persion.class);

                log.info("--延迟队列处理动态配置的任务 - 只针对延时发送的逻辑-发送消息：msg={},ttl={}", data, ttl);
                return message;
            });
        }
    }
}
